package com.rc.saas.tenant.common.utils;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by sven on 2018-05-10
 */
public class QrcodeUtil {
    /*字符集*/
    private static String DEFAULT_CHARSET = "UTF-8";

    /*算法*/
    private static String ALGORITHM_MD5 = "MD5";

    /*图片类型*/
    private static String IMAGE_TYPE_BMP = "bmp";
    private static String IMAGE_TYPE_GIF = "gif";
    private static String IMAGE_TYPE_JPG = "jpg";
    private static String IMAGE_TYPE_PNG = "png";

    /*二维码尺寸*/
    private static int QRCODE_DEFAULT_WIDTH = 300;
    private static int QRCODE_DEFAULT_HEIGHT = 300;

    public static BitMatrix encode(String text, String charset, int width, int height) {
        try {
            Map<EncodeHintType, String> hints = new HashMap<EncodeHintType, String>();
            hints.put(EncodeHintType.CHARACTER_SET, charset);
            return new MultiFormatWriter().encode(text, BarcodeFormat.QR_CODE, width, height, hints);
        } catch (WriterException e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    public static void encodeToOutputStream(String text, String charset, int width, int height,
                                            OutputStream outputStream) {
        try {
            BitMatrix bitMatrix = encode(text, charset, width, height);
            MatrixToImageWriter.writeToStream(bitMatrix, IMAGE_TYPE_PNG, outputStream);
        } catch (IOException e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    public static byte[] encodeToByteArray(String text, String charset, int width, int height) {
        try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
            encodeToOutputStream(text, charset, width, height, byteArrayOutputStream);
            return byteArrayOutputStream.toByteArray();
        } catch (IOException e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    public static byte[] encodeToByteArray(String text, String charset) {
        return encodeToByteArray(text, charset, QRCODE_DEFAULT_WIDTH, QRCODE_DEFAULT_HEIGHT);
    }

    public static byte[] encodeToByteArray(String text, int width, int height) {
        return encodeToByteArray(text, DEFAULT_CHARSET, width, height);
    }

    public static byte[] encodeToByteArray(String text) {
        return encodeToByteArray(text, DEFAULT_CHARSET,
                QRCODE_DEFAULT_WIDTH, QRCODE_DEFAULT_HEIGHT);
    }

    public static String encodeToBase64(String text, String charset, int width, int height) {
        try {
            return new String(Base64Util.encode(encodeToByteArray(text, charset, width, height)), charset);
        } catch (IOException e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    public static String encodeToBase64(String text, String charset) {
        return encodeToBase64(text, charset, QRCODE_DEFAULT_WIDTH, QRCODE_DEFAULT_HEIGHT);
    }

    public static String encodeToBase64(String text, int width, int height) {
        return encodeToBase64(text, DEFAULT_CHARSET, width, height);
    }

    public static String encodeToBase64(String text) {
        return encodeToBase64(text, DEFAULT_CHARSET,
                QRCODE_DEFAULT_WIDTH, QRCODE_DEFAULT_HEIGHT);
    }
}
